package xx.services.management.rest;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.sql.RowSet;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;

import xx.entity.manage.Account;
import xx.entity.manage.Resource;
import xx.entity.manage.Role;
import xx.entity.manage.SystemConfig;
import xx.listener.StartupListener;
import xx.services.Passport;
import xx.services.management.inter.IManagerInterface;
import xx.services.util.Constants;
import xx.util.string.Format;

/**
 * 后台帐号管理服务接口
 * 
 * @Path (Constants.RESTFUL_ROOT_PATH + "/account")
 * @author dengjinye,2010-12-20 $LastChangedDate$ $Author$
 */
@Path(Constants.RESTFUL_ROOT_PATH + "/account")
public class ManageRest extends Passport implements IManagerInterface
{

    public ManageRest(@Context HttpServletRequest request)
    {
        super(request);
        // TODO Auto-generated constructor stub
    }

    /**
     * 增加管理员帐号
     * 
     * @POST
     * @param username
     *            -@FormParam("username")
     *            管理员帐号
     * @param password
     *            -@FormParam("password")
     *            管理员密码
     * @param role
     *            -@DefaultValue("0")@FormParam("role")
     *            管理员角色
     * @param description
     *            -@FormParam("description")
     *            管理员描述
     * @return 新增的管理员实体
     */
    @POST
    public String addManager(@FormParam("username") String username, @FormParam("password") String password, @DefaultValue("0") @FormParam("role_id") long roleId, @FormParam("description") String description)
    {
        try
        {
            Account user = new Account(qr, owner);
            user.setUsername(username).setPassword(password).setRoleId(roleId).setDescription(description);
            user.insert();
            return ok(true);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 删除管理员。<br>
     * 
     * @DELETE
     * @Path ("/{user_id}")
     * @param userId
     *            -@PathParam("user_id")
     *            管理员ID，多个id用“_”间隔<br>
     * @return {result:number}表示成功，{result:String}表示失败，String就是失败原因描述。
     * @author dengjinye,2010-12-9
     */
    @DELETE
    @Path("/{user_id}")
    public String deleteManager(@PathParam("user_id") String userId)
    {
        try
        {
            long[] userIdArr = Format.strTolongArray(userId, "_");
            int count = 0;
            for (long id : userIdArr)
            {
                Account user = new Account(qr, owner);
                count += user.setUserId(id).delete();
            }
            return ok(count);
        }
        catch (SQLException e)
        {
            return error(e);
        }
    }

    /**
     * 获取管理员详细信息
     * 
     * @GET
     * @Path ("/{user_id}")
     * @param userId
     *            -@PathParam("user_id")
     *            管理员ID，多个id用“_”间隔<br>
     * @return 管理员实体
     */
    @GET
    @Path("/{user_id}")
    public String getManagerInfo(@PathParam("user_id") long userId)
    {
        try
        {
            Account user = new Account(qr, owner);
            user.setUserId(userId).load();
            return ok(user);
        }
        catch (SQLException e)
        {
            return error(e);
        }
    }

    /**
     * 获取管理员列表，只能获取自己有权限的管理员
     * 
     * @GET
     * @return 管理员实体列表
     */
    @GET
    public String getManagerList()
    {
        Account account = new Account(qr, owner);
        try
        {
            String cond = Format.isEmpty(condition) ? "1 and 1" : condition;
            Role role = account.setUserId(owner.userId).getRole();
            cond += " and role<=" + role.getRole();
            RowSet rs = account.getAccountRowSet(pageSize, pageNo, cond, orderField);
            Map<String, Object> map = new HashMap<String, Object>();
            if (isTotal)
            {
                map.put(Constants.TOTAL, account.getAccountCount(cond));
            }
            return ok(rs, map);
        }
        catch (SQLException e)
        {
            return error(e);
        }
    }

    /**
     * 获取角色列表，只能获取小于或等于自己角色的角色列表
     * 
     * @GET
     * @Path ("/role")
     * @return 角色列表
     */
    @GET
    @Path("/role")
    public String getRoles()
    {
        try
        {
            HttpSession session = request.getSession();
            int role = (Integer) session.getAttribute(Constants.ROLE);
            Role r = new Role(qr, owner);
            RowSet rs = r.setRole(role).getRoleRowSet();
            return ok(rs);
        }
        catch (SQLException e)
        {
            return error(e);
        }
    }

    /**
     * 管理员登陆<br>
     * 注：输入错达3次后，15分钟内禁止登陆
     * 
     * @POST
     * @Path ("/login")
     * @param username
     *            -@FormParam("username")
     *            管理员帐号
     * @param password
     *            -@FormParam("password")
     *            管理员密码
     * @return
     */
    @POST
    @Path("/login")
    public String login(@FormParam("username") String username, @FormParam("password") String password)
    {
        try
        {
            Object o = session.getAttribute("error");
            int e = Integer.valueOf("" + (o == null ? 0 : o));

            if (e >= 3)
            {
                return error("登陆失败：输入错误次数已达3次，请在15分钟后重试！");
            }

            Account account = new Account(qr, owner);
            boolean isLogin = account.setUsername(username).setPassword(password).login();
            if (!isLogin)
            {
                e++;
                session.setAttribute("error", e);

                if (e == 3)
                {
                    final Timer timer = new Timer();
                    timer.schedule(new TimerTask()
                    {
                        @Override
                        public void run()
                        {
                            // TODO Auto-generated method stub
                            session.invalidate();
                            timer.cancel();
                        }
                    }, 15/* 分钟 */* 60/* 秒钏 */* 1000/* 毫秒 */);
                }

                return error("登陆失败：用户名或密码不正确，请查证！<br>注：错误次数达3次时，15分钟内禁止登陆。<br>目前是第<b><font color=red>" + e + "</font></b>次错误");
            }

            session.setAttribute(SystemConfig.SYSTEM_NAME, SystemConfig.systemName);
            session.setAttribute(Constants.ACCOUNT, account);
            session.setAttribute(Constants.USER_ID, account.getUserId());
            session.setAttribute(Constants.USERNAME, username);
            session.setAttribute(Constants.IS_LOGIN, true);
            session.setAttribute(Constants.JSESSIONID, session.getId());
            session.setAttribute(Constants.X_FORWARDED_FOR, request.getHeader("x-forwarded-for"));
            session.setAttribute(Constants.HOST, request.getHeader("host"));
            Role role = account.getRole();
            session.setAttribute(Constants.ROLE, role.getRole());
            // Resource resource = role.getResource();
            // session.setAttribute

            return ok(account);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 退出登陆
     * 
     * @GET
     * @Path ("/logout")
     * @return
     */
    @GET
    @Path("/logout")
    public String logout()
    {
        try
        {
            session.invalidate();
            return ok(true);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 修改管理员
     * 
     * @PUT
     * @Path ("/{user_id}")
     * @param userId
     *            -@PathParam("user_id")
     *            管理员ID
     * @param username
     *            -@FormParam("username")
     *            管理员帐号
     * @param password
     *            -@FormParam("password")
     *            管理员密码
     * @param role
     *            -@FormParam("role")
     *            管理员角色，不能修改大于自己的权限
     * @param description
     *            -@FormParam("description")
     *            管理员描述
     * @return 新的管理员实体
     */
    @PUT
    @Path("/{user_id}")
    public String updateManager(@PathParam("user_id") long userId, @FormParam("username") String username, @FormParam("password") String password, @FormParam("role_id") long roleId, @FormParam("description") String description)
    {
        try
        {
            Account user = new Account(qr, owner);
            user.setUserId(userId).load();

            // 不能修改与自己同级，或比自己高级的用户信息
            long curUserId = (Long) session.getAttribute(Account.USER_ID);
            Account curUser = new Account(qr, owner);
            curUser.setUserId(curUserId).load();
            if (curUserId != userId && user.getRoleId() >= curUser.getRoleId())
            {
                return error("不能修改与自己同级，或比自己高级的用户信息。");
            }

            StringBuilder condition = new StringBuilder();
            if (username != null && !"".equals(username.trim()))
            {
                condition.append(Account.USERNAME + ",");
                user.setUsername(username);
            }
            if (password != null && !"".equals(password.trim()))
            {
                condition.append(Account.PASSWORD + ",");
                user.setPassword(password);
            }
            if (roleId > 0)
            {
                condition.append(Account.ROLE_ID + ",");
                user.setRoleId(roleId);
            }
            if (description != null && !"".equals(description.trim()))
            {
                condition.append(Account.DESCRIPTION);
                user.setDescription(description);
            }
            if (condition.length() > 0)
            {
                user.update(condition.toString());
            }
            return ok(user);
        }
        catch (SQLException e)
        {
            return error(e);
        }
    }
}
